微信小程序web

您所在的位置:网站首页 web 小程序 微信小程序web

微信小程序web

2023-12-08 21:50| 来源: 网络整理| 查看: 265

一、背景

基于微信公众号做了一个H5的项目; (因为是一款电子名片,所以需要挂公众号得到微信JS-SDK的部分API支持,例如:自定义分享、打开内置地图等); 现在需要优雅的获取用户手机号这个功能,就考虑到使用小程序的有这个API,但又不想重构项目,所以就查资料文档看见了小程序可以使用web-view标签实现在一个小程序中内嵌H5页面; 注意:

web-view标签官方描述:承载网页的容器,会自动铺满整个小程序页面,个人类型的小程序暂不支持使用。 web-view中的网页必须是https,需要在小程序后台添加为业务域名,添加时会请求根域名下是否存在校验文件,所以添加业务域名提供了一个校验文件需要下载后放到网页服务器下,保证https://domain/校验文件名.txt能被访问到。 web-view中的网页如果包含iframe,则iframe也要符合第二点要求。 二、小程序向嵌套H5传参 方式一(最容易想到的)

但是我们获取手机号其实获取的是一个code需要传给后端,但是我不想在小程序中放业务请求的代码了,于是利用动态指定web-view的src属性将code给到项目的url,实现了小程序向网页传参,这是我用到的第一种方式;

方式二(官方开放的方式)

ps: 嵌套的H5需要引入微信JS-SDK,引入后可以支持比公众号更多的API,此处传参在H5中使用的是wx.miniProgram.postMessage向小程序发送消息,会在特定时机(小程序后退、组件销毁、分享)触发小程序web-view标签所在组件的message事件。 web-view标签官方文档

属性:bindmessage             类型:eventhandler(事件回调函数)

小程序中web-view标签所在的页面会在(小程序后退、组件销毁、分享)触发并收到H5页面网页向小程序 postMessage(也就是在H5中调用wx.miniProgram.postMessage,需要提前写好,相当于埋个地雷,小程序在上述时机H5中的postMessage代码就会自动调用)。

wx.miniProgram.postMessage({ data: { cardId: 0, title: '电子名片' } })

小程序中通过绑定事件的回调进行调用:

bindGetMsg(e){ this.setData({ shareObj: e.detail.data[e.detail.data.length - 1] }) }

e.detail = { data },data是多次 postMessage 的参数组成的数组,所以一般每次我们都是用最新的数组最后一项;数组如下图; image 我通过第二种方式来实现了名片分享,通过小程序分享时通过H5将当前名片的id传给小程序; 比如我分享出去小程序的路径可能是 '/pages/card/index?id=20' 点击进入的时候我会把这个id通过动态指定web-view的src传递给H5; 然后H5就可以实现根据Id导航到相应的页面,比如这个id和当前用户id一致就去我的名片详情页,不一致则会跳转到他人名片详情页;

方式三(还得靠百度,搜到了一位老哥的方法)

在描述具体方法前,让我们先回顾一下上面背景里的注意里的第三点吧,没有这个第三点我也不会去百度的,自然也就不会写这个分享。 因为这个第3点,我本来H5中使用了腾讯位置服务的地图选点组件,是基于iframe来实现的,现在好家伙腾讯这边把自己的服务都没有设为白名单,我必须要换另一种方案实现用户地图选点功能; 让我们先来看看腾讯位置服务的地图选点组件如何使用:

window.addEventListener('message', function(event) { // 接收位置信息,用户选择确认位置点后选点组件会触发该事件,回传用户的位置信息 var loc = event.data; if (loc && loc.module 'locationPicker') {//防止其他应用也会向该页面post信息,需判断module是否为'locationPicker' console.log('location', loc); } }, false); 如果没有上述的第3点,我可以很舒服按照上面的方式将这个iframe放在我的页面的一个弹出层中; 我点击地图选点按钮后弹出这个iframe界面,当我确定选择好位置后我可以在上面代码的回调中拿到iframe传给我的数据(包含位置名称以及经纬度等信息,用于H5使用wx.openLocation打开微信内置地图) 但是第三点确实没办法,我就开始了百度曲线救国,搜小程序web-view与小程序通信,就这样打开了无数个标签页,终于直到我打开了一个简书的页面后,有了新奇的方法,有作者的演示gif,而且作者还放了Demo小程序的github链接以及详细的ReadMe文档,我马上把代码拉了下来,开始跑一下,但是直接报错了。。。

仓库截图如下: image

上图是原作者的Demo仓库文件结构,web-view为小程序文件夹,下面webview.html为小程序中的嵌套H5页面,报错原因是H5页面中通过cdn引入的qs库链接失效了,于是将其替换为可使用的cdn链接继续开始跑,果然可以传参过去,我瞬间充满了希望!

其大致原理是在小程序中通过全局函数getCurrentPages 可以拿到当前小程序的页面栈,通过修改页面栈中web-view所在页面的web_view_src属性从而使H5监听到hashchange事件; 同时在H5中监听window的hashchange事件,改变时就去取hash的查询参数部分;

const url = 'https:www.abcd.com/#/layout/mycard?参数1=123&参数2=234'

此时通过qs将search部分转换为js对象,然后再history.back()恢复为传参之前的url(恢复是为了下一次传参不会受影响,要不然url会一直拼接),因为只是hash部分改变所以不会刷新页面;从而拿到小程序传递的数据;部分代码如下图: image 原作者代码中除了之前的==qs库cdn链接失效==外,还有一个小问题就是他的微信基础库版本很低他的是2.10左右的,我的基础库版本是最新的,参考他的核心代码发现我的一直实现不了,我以为是Vue项目可能不能用,因为他demo不是vue网页,但是我还是抱着试试看的心态搞了一晚上,还是没弄出来,直到第二天早上我摸索了一下,我去打印上图代码中的prePage,发现里面的属性是web_view_src,作者之前可能因为微信基础库版本不同,他的参数就是visitUrl,在作者Demo中只需要将qs库cdn正确映入后就可以跑通看到效果,因为Demo小程序中自带基础库版本号,开发工具会自动识别;

prevPage.setData({visitUrl});

在我打印页面栈对象prePage后,我发现属性变了,于是我就去把属性visitUrl改成了web_view_src如下,然后在我的项目中就可以正常传参使用了!!!

prevPage.setData({ web_view_src:visitUrl, });

而且我在调试过程中发现微信开发工具可以调试web-view里的网页,在web-view所在页面开发工具模拟器底部会出现这个按钮,点击就弹出一个像H5控制台的界面了; image 但是很神奇的是打开这个控制台后会发生问题,就是页面监听不到hashchange事件了,也就是说如果你正在调试利用 当前方法传参就不要打开那个控制台,控制台打开后H5中不通过hashchange事件控制的其余代码也会有异常,例如下面这段代码;

function test(){ alert('大家好') console.log('我是张三') alert('我的发言结束') } test() //我们预期点击按钮执行该函数,而且是第一个alert确认后才会打印然后第二个alert开始执行; //但是此时运行结果会是第一个alert忽略不执行,接着直接打印,最后执行第二个alert;

以上情况可能与版本库有关系,只为了说明开发工具中可能存在出乎意料的小惊喜,不能抱着常规的调试心态去调试,要大胆猜想并通过代码自测,还挺好玩(玩出来了就好玩,没玩出来嘛就.....f**k)

结束

谢谢你的阅读,排版不太会排,多担待。。。 下面是原作者的简书地址以及github中的Demo地址,感谢老哥的分享。 大家可以试试,读一下这位老哥的代码,理解一下原理,万一要用就可以手到擒来。

原作者简书地址,点击跳转

原作者Demo仓库地址,点击跳转

原作者附加:Uniapp与webview通信用法,点击跳转



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3